﻿using Messhall.Framework.Domain.DomainObject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;

namespace Messhall.Framework.Domain.Repository
{
    public interface IRepositoryReadBase<BoT, TEntity> : IRepositoryReadSqlBase
        where BoT : BoBase
        where TEntity : EntityBase
    {
        /// <summary>
        /// 根据keyId寻找业务对象
        /// </summary>
        /// <returns>KeyId所对应的业务对象，或者NULL</returns>
        Task<BoT> FindAsync(Guid keyId);

        /// <summary>
        /// 根据keyId寻找业务对象
        /// </summary>
        /// <returns>KeyId所对应的业务对象，或者NULL</returns>
        Task<List<BoT>> FindAsync(params Guid[] keyId);

        /// <summary>
        /// 根据给定的搜索条件寻找业务对象
        /// </summary>
        /// <param name="fliter">搜索条件</param>
        /// <returns></returns>
        Task<IList<BoT>> FindAsync(Expression<Func<TEntity, bool>> fliter);


        /// <summary>
        /// 寻找业务所有对象
        /// </summary>
        Task<List<BoT>> FindAllAsync();

        /// <summary>
        /// 根据给定的搜索条件寻找业务对象，返回列表按照给定的方式排序
        /// </summary>
        /// <param name="fliter">搜索条件</param>
        /// <param name="sortCriteria">排序方式</param>
        /// <param name="ascending">倒叙还是正序</param>
        /// <returns></returns>
        Task<IList<BoT>> FindBySortAsync<Sort>(Expression<Func<TEntity, bool>> fliter,
            Expression<Func<TEntity, Sort>> sortCriteria, bool ascending = true);

        /// <summary>
        /// 根据给定的搜索条件寻找业务对象
        /// </summary>
        /// <param name="fliter">搜索条件</param>
        /// <param name="sortCriteria">排序方式</param>
        /// <param name="pageIndex">页码号，从1开始</param>
        /// <param name="pageSize">每页的对象个数</param>
        /// <param name="ascending">倒叙还是正序</param>
        /// <returns></returns>
        Task<(IList<BoT>, int)> FindPagingAsync<Sort>(Expression<Func<TEntity, bool>> fliter,
            Expression<Func<TEntity, Sort>> sortCriteria, int? pageIndex, int? pageSize, bool ascending = true);


        /// <summary>
        /// 根据给定的搜索条件寻找最大值
        /// </summary>
        /// <param name="fliter"></param>
        /// <param name="maxCriteria"></param>
        /// <typeparam name="TValue"></typeparam>
        /// <returns></returns>
        Task<TValue> FindMaxAsync<TValue>(Expression<Func<TEntity, bool>> fliter,
            Expression<Func<TEntity, TValue>> maxCriteria);
    }
}